﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;
using System.IO;
namespace lesson6
{
    // 客户类
    public class Customer
    {
        public string Name { get; set; }
        public override string ToString() => $"Customer: {Name}";
    }

    // 商品类
    public class Product
    {
        public string Name { get; set; }
        public double Price { get; set; }
        public override string ToString() => $"Product: {Name}, Price: {Price}";
    }

    // 订单明细类
    public class OrderDetails
    {
        public Product Product { get; set; }
        public int Quantity { get; set; }
        public double Amount => Product.Price * Quantity;

        public override bool Equals(object obj)
        {
            return obj is OrderDetails detail &&
                   Product.Name == detail.Product.Name;
        }

        public override int GetHashCode() => Product.Name.GetHashCode();

        public override string ToString() => $"{Product}, Quantity: {Quantity}, Total: {Amount}";
    }

    // 订单类
    public class Order
    {
        public int OrderId { get; set; }
        public Customer Customer { get; set; }
        public List<OrderDetails> Details { get; set; } = new List<OrderDetails>();
        public double TotalAmount => Details.Sum(d => d.Amount);

        public override bool Equals(object obj)
        {
            return obj is Order order &&
                   OrderId == order.OrderId;
        }

        public override int GetHashCode() => OrderId.GetHashCode();

        public override string ToString()
        {
            string detailStr = string.Join("\n  ", Details.Select(d => d.ToString()));
            return $"OrderId: {OrderId}, {Customer}, Total: {TotalAmount}\n  {detailStr}";
        }
    }

    // 订单服务类
    public class OrderService
    {
        private List<Order> orders = new List<Order>();

        public void ExportToXml(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath))
                throw new ArgumentException("文件路径不能为空");

            var serializer = new XmlSerializer(typeof(List<Order>));
            using (var writer = new StreamWriter(filePath))
            {
                serializer.Serialize(writer, orders);
            }
        }

        public void ImportFromXml(string filePath)
        {
            if (!File.Exists(filePath))
                throw new FileNotFoundException("文件不存在", filePath);

            var serializer = new XmlSerializer(typeof(List<Order>));
            using (var reader = new StreamReader(filePath))
            {
                var importedOrders = (List<Order>)serializer.Deserialize(reader);
                orders.Clear();
                orders.AddRange(importedOrders);
            }
        }

        public void AddOrder(Order order)
        {
            if (orders.Contains(order))
                throw new Exception("订单已存在！");
            orders.Add(order);
        }

        public void DeleteOrder(int orderId)
        {
            var order = orders.FirstOrDefault(o => o.OrderId == orderId);
            if (order == null)
                throw new Exception("订单不存在！");
            orders.Remove(order);
        }

        public void ModifyOrder(int orderId, Order newOrder)
        {
            var index = orders.FindIndex(o => o.OrderId == orderId);
            if (index == -1)
                throw new Exception("修改失败：订单不存在！");
            orders[index] = newOrder;
        }

        public List<Order> QueryOrders(Func<Order, bool> predicate)
        {
            return orders
                .Where(predicate)
                .OrderByDescending(o => o.TotalAmount)
                .ToList();
        }

        public void SortOrders(Func<Order, object> keySelector = null)
        {
            keySelector ??= o => o.OrderId;
            orders = orders.OrderBy(keySelector).ToList();
        }

        public void ShowAllOrders()
        {
            foreach (var order in orders)
                Console.WriteLine(order);
        }
    }

    // Person类（用于反射）
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public override string ToString() => $"Person(Name={Name}, Age={Age})";
    }

    class Program
    {
        static void Main(string[] args)
        {
            OrderService service = new OrderService();

            var product1 = new Product { Name = "Apple", Price = 3.0 };
            var product2 = new Product { Name = "Book", Price = 15.0 };
            var customer = new Customer { Name = "Alice" };

            // 添加订单
            var order1 = new Order
            {
                OrderId = 1,
                Customer = customer,
                Details = new List<OrderDetails>
                {
                    new OrderDetails { Product = product1, Quantity = 5 },
                    new OrderDetails { Product = product2, Quantity = 2 }
                }
            };

            try
            {
                service.AddOrder(order1);
            }
            catch (Exception e)
            {
                Console.WriteLine("添加失败：" + e.Message);
            }

            // 查询订单（按客户名）
            Console.WriteLine("\n查询订单（客户名为Alice）");
            var results = service.QueryOrders(o => o.Customer.Name == "Alice");
            results.ForEach(Console.WriteLine);

            // 删除订单
            try
            {
                service.DeleteOrder(2); // 不存在
            }
            catch (Exception e)
            {
                Console.WriteLine("删除失败：" + e.Message);
            }

            // 排序演示
            Console.WriteLine("\n所有订单：");
            service.SortOrders(o => o.TotalAmount);
            service.ShowAllOrders();

            // f2. 生成100个随机整数，排序，求和与平均数
            var rand = new Random();
            var nums = Enumerable.Range(0, 100).Select(_ => rand.Next(0, 1001)).ToList();
            var sortedNums = nums.OrderByDescending(n => n);
            Console.WriteLine("\n前10个排序后的随机数：" + string.Join(", ", sortedNums.Take(10)));
            Console.WriteLine($"总和: {nums.Sum()}, 平均: {nums.Average():F2}");

            // f3. 使用反射调用构造方法创建Person对象
            Console.WriteLine("\n反射创建Person对象：");
            Type personType = typeof(Person);
            var ctor = personType.GetConstructor(new[] { typeof(string), typeof(int) });
            var personInstance = ctor.Invoke(new object[] { "Tom", 30 }) as Person;
            Console.WriteLine(personInstance);
        }
    }
}
